package com.wcs.exam.common.log;

import cn.hutool.core.bean.BeanUtil;
import com.wcs.exam.common.base.Result;
import com.wcs.exam.common.base.annotation.OptLogCache;
import com.wcs.exam.common.cache.CacheRedis;
import com.wcs.exam.common.config.ThreadContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@RequiredArgsConstructor
@Slf4j
@Aspect
@Component
public class AspectOptLogCache {

    @NotNull
    private final CacheRedis cacheRedis;

    @Pointcut("@annotation(com.wcs.exam.common.base.annotation.OptLogCache)")
    public void cacheLogPointCut() {

    }

    @AfterReturning(value = "cacheLogPointCut()", returning = "obj")
    public void afterReturning(JoinPoint joinPoint, Object obj) {
        if (obj instanceof Result<?> result) {
            // 判断是否查询成功
            if (!Objects.equals(result.getCode(), Result.SUCCESS)) {
                return;
            }

            // 获取查询结果
            Map<String, Object> dataMap = BeanUtil.beanToMap(result.getData());
            if (dataMap == null || !dataMap.containsKey("id")) {
                return;
            }

            // 获取注解信息
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            OptLogCache sysLogCache = signature.getMethod().getAnnotation(OptLogCache.class);
            if (sysLogCache == null) {
                return;
            }

            // 缓存查询结果
            String cacheKey = sysLogCache.key() + ThreadContext.getUserId() + dataMap.get("id");
            cacheRedis.set(cacheKey, dataMap, 120, TimeUnit.MINUTES);
        }
    }
}
